home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
graphics
/
gnuplot
/
contrib
/
hanna
/
gnulib_x11.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-16
|
9KB
|
333 lines
#ifndef lint
static char *RCSid = "$Id: gnulib_x11.c,v 1.00 1992/03/31 18:03:00 gregor Exp gregor $";
#endif
/*
* $Log: gnulib_x11.c,v $
* Revision 1.00 1992/03/31 18:03:00 gregor
* gnuplot3.2, beta 6
*
*/
/*-----------------------------------------------------------------------------
* gnulib_x11 - linkable X11 outboard terminal driver for gnuplot 3
*
* Based on gnuplot_x11.c by Ed Kubaitis (University of Illinois)
*
* This code is provided as is and with no warranties of any kind.
*
* gregg hanna (gregor@kafka.saic.com)
* Science Applications International Corporation
*---------------------------------------------------------------------------*/
#include "gnulib_x11.h"
#define Ncolors 13
static Pixel *colors;
static XFontStruct *font;
static Display *dpy;
static Drawable pixmap;
static char dashes[10][5] = { {0}, {1,6,0},
{0}, {4,2,0}, {1,3,0}, {4,4,0}, {1,5,0}, {4,4,4,1,0}, {4,2,0}, {1,3,0}
};
static int cx=0, cy=0, vchar;
static enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
/*-----------------------------------------------------------------------------
* GP_PlotFromStream - reads a gnuplot (xlib) from an open stream
*---------------------------------------------------------------------------*/
int GP_PlotFromStream(fp,disp,pmap,colortable,ufont)
FILE *fp;
Display *disp;
Drawable pmap;
Pixel *colortable;
XFontStruct *ufont;
{
int i;
static int accept();
if ( colortable == NULL ) return -1;
colors = colortable;
font = ufont;
dpy = disp;
pixmap = pmap;
while (!(i=accept(fp)));
return i;
}
/*-----------------------------------------------------------------------------
* GP_PlotFromFile - reads a gnuplot from a file, drawing it in a pixmap
*---------------------------------------------------------------------------*/
int GP_PlotFromFile(fn,disp,pmap,colortable,ufont)
char *fn;
Display *disp;
Drawable pmap;
Pixel *colortable;
XFontStruct *ufont;
{
FILE *fp;
int i;
fp = fopen(fn,"r");
if ( fp == NULL ) return -1;
i = GP_PlotFromStream(fp,disp,pmap,colortable,ufont);
fclose(fp);
return i;
}
/*-----------------------------------------------------------------------------
* accept - accept & record new plot from gnuplot inboard X11 driver
*---------------------------------------------------------------------------*/
#define NBUF 1024
static int nc = 0;
static int ncalloc = 0;
static char **commands = (char**)0;
static int accept(f)
FILE *f;
{
char buf[NBUF];
/*
static int display();
*/
int display();
while (fgets(buf, NBUF, f)) {
if (*buf == 'G') { /* enter graphics mode */
if (commands) {
int n; for (n=0; n<nc; n++) free(commands[n]);
free(commands);
}
commands = (char **)0; nc = ncalloc = 0;
}
else if (*buf == 'E') { /* leave graphics mode */
display();
if (commands) {
int n; for (n=0; n<nc; n++) free(commands[n]);
free(commands);
}
commands = (char **)0; nc = ncalloc = 0;
return 0;
}
else if (*buf == 'R') { return 1; } /* leave X11/x11 mode */
else { /* record command */
char *p;
if (nc >= ncalloc) {
ncalloc = ncalloc*2 + 1;
commands = (commands)
? (char **)realloc(commands, ncalloc * sizeof(char *))
: (char **)malloc(sizeof(char *));
}
p = (char *)malloc((unsigned)strlen(buf)+1);
if (!commands || !p) return -1;
commands[nc++] = strcpy(p, buf);
}
}
}
/*-----------------------------------------------------------------------------
* display - display last plot from gnuplot inboard X11 driver
*---------------------------------------------------------------------------*/
#define X(x) (int) (x * xscale)
#define Y(y) (int) ((4095-y) * yscale)
int display()
{
int n, x, y, sw, sl, lt, width, type, W, H;
char *buf, *str;
double xscale, yscale;
Window root;
unsigned int d0;
int d1, myfont;
GC gc;
XGetGeometry(dpy,pixmap,&root,&d0,&d0,&W,&H,&d1,&d1);
if (!nc) return;
/* set scaling factor between internal driver & window geometry */
xscale = (double)W / 4096.; yscale = (double)H / 4096.;
gc = XCreateGC(dpy,pixmap,0,(XGCValues*)NULL);
/* set font parameters */
myfont = 0;
if ( font == NULL ) {
font = XLoadQueryFont(dpy,"9x15");
if ( font != NULL ) myfont = 1;
}
if ( font != NULL ) XSetFont(dpy,gc,font->fid);
if ( font == NULL ) vchar = 30;
else vchar = font->ascent + font->descent;
/* set pixmap background */
XSetForeground(dpy, gc, colors[0]);
XSetBackground(dpy, gc, colors[0]);
/* loop over accumulated commands from inboard driver */
for (n=0; n<nc; n++) {
buf = commands[n];
/* X11_vector(x,y) - draw vector */
if (*buf == 'V') {
sscanf(buf, "V%4d%4d", &x, &y);
XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
cx = x; cy = y;
}
/* X11_move(x,y) - move */
else if (*buf == 'M')
sscanf(buf, "M%4d%4d", &cx, &cy);
/* X11_put_text(x,y,str) - draw text */
else if (*buf == 'T') {
sscanf(buf, "T%4d%4d", &x, &y);
str = buf + 9; sl = strlen(str) - 1;
sw = 0;
if ( font != NULL ) {
sw = XTextWidth(font, str, sl);
switch(jmode) {
case LEFT: sw = 0; break;
case CENTRE: sw = -sw/2; break;
case RIGHT: sw = -sw; break;
}
}
XSetForeground(dpy, gc, colors[2]);
XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
XSetForeground(dpy, gc, colors[lt+3]);
}
/* X11_justify_text(mode) - set text justification mode */
else if (*buf == 'J')
sscanf(buf, "J%4d", &jmode);
/* X11_linetype(type) - set line type */
else if (*buf == 'L') {
sscanf(buf, "L%4d", <);
lt = (lt%8)+2;
width = (lt == 0) ? 2 : 0;
if (colors[Ncolors] == (Pixel)0) {
/* not monochrome */
if (lt != 1)
type = LineSolid;
else {
type = LineOnOffDash;
XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
}
XSetForeground(dpy, gc, colors[lt+3]);
}
else {
/* monochrome */
type = (lt == 0 || lt == 2) ? LineSolid : LineOnOffDash;
if (dashes[lt][0])
XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
}
XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
}
}
XFreeGC(dpy,gc);
if (myfont) XFreeFont(dpy,font);
}
/*-----------------------------------------------------------------------------
* pr_color - determine color values
*---------------------------------------------------------------------------*/
Pixel *GP_ColorArray(bg,fg,c0,c1,c2,c3,c4,c5,c6,c7,c8)
Pixel bg,fg,c0,c1,c2,c3,c4,c5,c6,c7,c8;
{
static Pixel colortable[Ncolors+1];
colors[0] = bg; /* background */
colors[1] = fg; /* bordercolor */
colors[2] = fg; /* text */
colors[3] = fg; /* border */
colors[4] = fg; /* axis */
colors[5] = c1;
colors[6] = c2;
colors[7] = c3;
colors[8] = c4;
colors[9] = c5;
colors[10] = c6;
colors[11] = c7;
colors[12] = c8;
colors[Ncolors] = (Pixel)0; /* not mono */
return colortable;
}
static char color_values[Ncolors][30] = {
"white", "black", "black", "black", "black",
"red", "green", "blue", "magenta",
"cyan", "sienna", "orange", "coral"
};
static char gray_values[Ncolors][30] = {
"black", "white", "white", "gray50", "gray50",
"gray100", "gray60", "gray80", "gray40",
"gray90", "gray50", "gray70", "gray30"
};
Pixel *GP_AllocColor(dpy,mode)
Display *dpy;
int mode;
{
Pixel black, white;
XColor used, exact;
Colormap cmap;
int n, Gray, Mono, Rv;
Pixel *colortable;
Visual *vis;
int scr;
char *v;
colortable = (Pixel*)calloc(sizeof(Pixel),Ncolors+1);
if (!colortable) return NULL;
scr = DefaultScreen(dpy);
black = BlackPixel(dpy,scr);
white = WhitePixel(dpy,scr);
switch (mode) {
case 0: /* figure it out */
Gray = Mono = Rv = 0;
vis = DefaultVisual(dpy,scr);
if ( vis->class == GrayScale || vis->class == StaticGray )
if ( DefaultDepth(dpy,scr) == 1 ) Mono = 1;
else Gray = 1;
break;
case 1: Gray = 0; Mono = 0; Rv = 0; break;
case 2: Gray = 1; Mono = 0; Rv = 0; break;
case 3: Gray = 0; Mono = 1; Rv = 0; break;
default: Gray = 0; Mono = 1; Rv = 1; break;
}
if (!Mono) {
cmap = DefaultColormap(dpy, scr);
for (n=0; n<Ncolors; n++) {
v = ((Gray) ? gray_values[n] : color_values[n]);
if (XAllocNamedColor(dpy, cmap, v, &used, &exact))
colortable[n] = used.pixel;
else {
/* fallback to monochrome */
Mono++;
break;
}
}
}
if (Mono) {
colortable[0] = (Rv) ? black : white ;
for (n=1; n<Ncolors; n++) colortable[n] = (Rv) ? white : black;
}
if ( Mono ) colortable[Ncolors] = (Pixel)1;
return colortable;
}